home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / smcpc.arc / CPCLIB.ASM < prev    next >
Assembly Source File  |  1988-01-19  |  16KB  |  1,054 lines

  1. page 60,132
  2. ;TITLE (C) Copyright CAPROCK SYSTEMS, INC. 1982
  3. ;SUBTTL small-c:PC PC-DOS RUN TIME LIBRARY
  4. ;
  5. ;
  6. DATASEG    SEGMENT    BYTE PUBLIC 'code'
  7.     DB    '(C) Copyright CAPROCK SYSTEMS, INC. 1982'
  8. ;
  9. ;
  10. ;
  11.                     ;FOR I/O BUFFERS
  12. FCBSIZE    EQU    40        ;PCDOS FCB SIZE + 3
  13. BUFFER    EQU    4        ;SPACE NEEDED FOR NEXT PTR AND UNUSED CNT
  14. BUFSIZ    EQU    512        ;DISK BLOCK SIZE
  15. NEXTP    EQU    0        ;OFFSET IN BUFFER OF NEXT CHAR PTR
  16. UNUSED    EQU    2        ;OFFSET IN BUFFER OF REMAINING CHARS
  17. FLAG    EQU    37        ;OFFSET IN FCB OF FLAG TYPING AN FCB
  18. NBUFS    EQU    4        ;NUMBER OF IOBUFS (SEE BELOW)
  19. FREEFLG    EQU    128        ;FCB NOT ALLOCATED
  20. EOFFLG    EQU    2        ;EOF ENCOUNTERED ON FILE
  21. WRTFLG    EQU    1        ;FILE OPENED FOR WRITING
  22. CTRLZ    EQU    26
  23. EOL    EQU    13        ;END OF LINE CHARACTER
  24. LF    EQU    10        ;LINE FEED
  25. ;
  26. ;PCDOS INT 21H FUNCTION CODES
  27. ;
  28. GETCH    EQU    1
  29. PUTCH    EQU    2
  30. GETSTR    EQU    10
  31. SELECT    EQU    14
  32. DMA    EQU    26
  33. OPEN    EQU    15
  34. DELETE    EQU    19
  35. CREATE    EQU    22
  36. CLOSE    EQU    16
  37. SEQREAD    EQU    20
  38. SEQWRITE EQU    21
  39. GETDFLT    EQU    25        ;GET CURRENT LOGGED DRIVE
  40. PARSE    EQU    41
  41. ;
  42. ;
  43. ; FCB STORAGE AND I/O BUFFERS
  44. ;
  45. DFLTDSK    DB    0        ;BYTE FOR DEFAULT DISK
  46. IOBUFS    DB    FCBSIZE-3 DUP(?)
  47.     DB    FREEFLG,0,0
  48.     DB    BUFFER+BUFSIZ DUP(?)
  49. ;
  50.     DB    FCBSIZE-3 DUP(?)
  51.     DB    FREEFLG,0,0
  52.     DB    BUFFER+BUFSIZ DUP(?)
  53. ;
  54.     DB    FCBSIZE-3 DUP(?)
  55.     DB    FREEFLG,0,0
  56.     DB    BUFFER+BUFSIZ DUP(?)
  57. ;
  58.     DB    FCBSIZE-3 DUP(?)
  59.     DB    FREEFLG,0,0
  60.     DB    BUFFER+BUFSIZ DUP(?)
  61. DATASEG    ENDS
  62. ;
  63. ;
  64. ;
  65. CSEG    SEGMENT    BYTE PUBLIC 'code'
  66.     ASSUME    CS:CSEG,DS:DATASEG
  67. ;-------------------------------------------------
  68. ;
  69. ;    Small-C:PC Run Time Library for IBM PC-DOS
  70. ;
  71. ;    V1    As of June, 1982
  72. ;
  73. ;--------------------------------------------------
  74.     db    '(C) Copyright CAPROCK SYSTEMS, INC. 1982'
  75. ;
  76. ;
  77. ; Fetch byte at offset BX in Stack Segment (SS) and sign extend into BX
  78. ;
  79.     PUBLIC    CCGCHAR
  80. CCGCHAR:
  81.     MOV    BP,BX
  82.     MOV    AL,[BP]
  83.     CBW
  84.     MOV    BX,AX
  85.     RET
  86. ;
  87. ; Fetch a 16-bit integer at offset BX in SS into BX
  88. ;
  89.     PUBLIC    CCGINT
  90. CCGINT:
  91.     MOV    BP,BX
  92.     MOV    BX,[BP]
  93.     RET
  94. ;
  95. ; Store BL into SS at offset in DX
  96. ;
  97.     PUBLIC    CCPCHAR
  98. CCPCHAR:
  99.     MOV    BP,DX
  100.     MOV    [BP],BL
  101.     RET
  102. ;
  103. ; Store BX into SS at Offset in DX
  104. ;
  105.     PUBLIC    CCPINT
  106. CCPINT:
  107.     MOV    BP,DX
  108.     MOV    [BP],BX
  109.     RET
  110. ;
  111. ; Multiply DX by BX and return result in BX
  112. ;
  113.     PUBLIC    CCMULT
  114. CCMULT:
  115.     MOV    AX,DX
  116.     IMUL    BX
  117.     MOV    BX,AX
  118.     RET
  119. ;
  120. ; Divide DX by BX, return quotient in BX, remainder in DX
  121. ;
  122.     PUBLIC    CCDIV
  123. CCDIV:
  124.     MOV    AX,DX
  125.     MOV    CX,1
  126.     IMUL    CX
  127.     IDIV    BX
  128.     MOV    BX,AX
  129.     RET
  130. ;
  131. ; Unsigned compare of DX to BX, carry set if DX < BX
  132. ;
  133.     PUBLIC    CCUCMP
  134. CCUCMP:
  135.     CMP    DH,BH
  136.     JNZ    CC@1
  137.     CMP    DL,BL
  138. CC@1:
  139.     MOV    BX,1
  140.     RET
  141. ;
  142. ; Test if DX >= BX (Unsigned)
  143. ;
  144.     PUBLIC    CCUGE
  145. CCUGE:
  146.     CALL    CCUCMP
  147.     JNC    CC@2
  148.     DEC    BX
  149. CC@2:
  150.     RET
  151. ;
  152. ; Test if DX < BX (Unsigned)
  153. ;
  154.     PUBLIC    CCULT
  155. CCULT:
  156.     CALL    CCUCMP
  157.     JC    CC@3
  158.     DEC    BX
  159. CC@3:
  160.     RET
  161. ;
  162. ; Test if DX > BX (Unsigned)
  163. ;
  164.     PUBLIC    CCUGT
  165. CCUGT:
  166.     XCHG    BX,DX
  167.     CALL    CCULT
  168.     RET
  169. ;
  170. ; Test if DX <= BX (Unsigned)
  171. ;
  172.     PUBLIC    CCULE
  173. CCULE:
  174.     XCHG    BX,DX
  175.     CALL    CCUGE
  176.     RET
  177. ;
  178. ; Signed Compare of DX and BX
  179. ;
  180. ; carry set if DX < BX, zero/non-zero set for equality
  181. ;
  182.     PUBLIC    CCCMP
  183. CCCMP:
  184.     SUB    DL,BL
  185.     SBB    DH,BH
  186.     MOV    BX,1
  187.     JS    CCCMP1
  188.     OR    DH,DL
  189.     RET
  190. CCCMP1:
  191.     OR    DH,DL
  192.     STC
  193.     RET
  194. ;
  195. ; Test if DX = BX and set BX=1 if true, else 0
  196. ;
  197.     PUBLIC    CCEQ
  198. CCEQ:
  199.     CALL    CCCMP
  200.     JZ    CC@4
  201.     DEC    BX
  202. CC@4:
  203.     RET
  204. ;
  205. ;
  206. ; Test if DX != BX
  207. ;
  208.     PUBLIC    CCNE
  209. CCNE:
  210.     CALL    CCCMP
  211.     JNZ    CC@5
  212.     DEC    BX
  213. CC@5:
  214.     RET
  215. ;
  216. ; Test if DX < BX
  217. ;
  218.     PUBLIC    CCLT
  219. CCLT:
  220.     CALL    CCCMP
  221.     JC    CC@6
  222.     DEC    BX
  223. CC@6:
  224.     RET
  225. ;
  226. ; Test if DX > BX
  227. ;
  228.     PUBLIC    CCGT
  229. CCGT:
  230.     XCHG    BX,DX
  231.     CALL    CCLT
  232.     RET
  233. ;
  234. ; Test if DX <= BX
  235. ;
  236.     PUBLIC    CCLE
  237. CCLE:
  238.     CALL    CCCMP
  239.     JC    CC@7
  240.     JZ    CC@7
  241.     DEC    BX
  242. CC@7:
  243.     RET
  244. ;
  245. ; Test if DX >= BX
  246. ;
  247.     PUBLIC    CCGE
  248. CCGE:
  249.     XCHG    BX,DX
  250.     CALL    CCLE
  251.     RET
  252. ;
  253. ;-------------------------------------------------
  254. ;
  255. ; PC-DOS I/O MODULES
  256. ; (C) CAPROCK SYSTEMS, INC.
  257. ; P.O. BOX 13814
  258. ; ARLINGTON, TEXAS 76013
  259. ;
  260. ;-------------------------------------------------
  261. ;
  262. ;
  263. ;
  264. ;    pcdos(ah,dx)
  265. ;
  266.     PUBLIC    QZPCDOS
  267. QZPCDOS:
  268.     POP    CX
  269.     POP    DX
  270.     POP    AX
  271.     PUSH    AX
  272.     PUSH    DX
  273.     PUSH    CX
  274.     MOV    AH,AL
  275.     INT    21H
  276.     CBW
  277.     MOV    BX,AX
  278.     RET
  279. ;
  280. ;
  281. ;    out808X(port,AL)
  282. ;
  283. ;
  284.     PUBLIC    QZOUT808X
  285. QZOUT808X:
  286.     POP    CX
  287.     POP    AX
  288.     POP    DX
  289.     PUSH    DX
  290.     PUSH    AX
  291.     OUT    DX,AL
  292.     JMP    CX
  293. ;
  294. ;
  295. ;    int var = in808X(port)
  296. ;
  297. ;
  298.     PUBLIC    QZIN808X
  299. QZIN808X:
  300.     POP    CX
  301.     POP    DX
  302.     PUSH    DX
  303.     IN    AL,DX
  304.     CBW
  305.     MOV    BX,AX
  306.     JMP    CX
  307. ;
  308. ;
  309. ;    VIDEO I/O THRU ROM BIOS
  310. ;
  311. ;    int10(AH,AL,BH,BL,CH,CL,DH,DL);
  312. ;
  313. ;
  314.     PUBLIC    QZINT10
  315. QZINT10:
  316.     POP    SI
  317.     POP    DX
  318.     POP    AX
  319.     MOV    DH,AL
  320.     POP    CX
  321.     POP    AX
  322.     MOV    CH,AL
  323.     POP    BX
  324.     POP    AX
  325.     MOV    BH,AL
  326.     MOV    DI,BX
  327.     POP    AX
  328.     POP    BX
  329.     MOV    AH,BL
  330.     MOV    BX,DI
  331.     PUSH    AX
  332.     PUSH    AX
  333.     PUSH    BX
  334.     PUSH    BX
  335.     PUSH    CX
  336.     PUSH    CX
  337.     PUSH    DX
  338.     PUSH    DX
  339.     PUSH    SI
  340.     INT    10H
  341.     RET
  342. ;
  343. ;
  344. ;    ASYNC I/O THRU ROM BIOS
  345. ;
  346. ;    BX = INT14(AH,AL,DX)
  347. ;
  348.     PUBLIC    QZINT14
  349. QZINT14:
  350.     POP    CX
  351.     POP    DX
  352.     POP    BX
  353.     POP    AX
  354.     PUSH    AX
  355.     PUSH    BX
  356.     PUSH    DX
  357.     MOV    AH,AL
  358.     MOV    AL,BL
  359.     INT    14H
  360.     MOV    BX,AX
  361.     JMP    CX
  362. ;
  363. ;
  364. ;    copy program prefix to stack area
  365. ;
  366. ;    copyprefix(ptr);
  367. ;
  368.     PUBLIC    QZCOPYPREF
  369. QZCOPYPREF:
  370.     POP    CX
  371.     POP    DI        ;OFFSET INTO STACK OF DESTINATION
  372.     PUSH    DI
  373.     PUSH    CX
  374.     MOV    AX,SS
  375.     PUSH    ES
  376.     MOV    ES,AX        ;PREPARE FOR MOVE
  377.     MOV    SI,0
  378.     CLD
  379.     MOV    CX,128        ;NUMBER WORDS TO MOVE
  380.     REP    MOVSW
  381.     POP    ES
  382.     RET
  383. ;
  384. ;
  385. ;    SOUND BELL
  386. ;
  387. ;    bell()
  388. ;
  389.     PUBLIC    QZBELL
  390. QZBELL:
  391.     MOV    AX,7        ;BELL CHARACTER
  392.     PUSH    AX
  393.     CALL    QZPUTCHAR    ;SOUND IT
  394.     POP    AX
  395.     RET
  396. ;
  397. ;
  398. ;    CLEAR SCREEN
  399. ;
  400. ;    clrscreen();
  401. ;
  402.     PUBLIC    QZCLRSCREE
  403. QZCLRSCREE:
  404.     INT    11H        ;EQUIPMENT
  405.     MOV    SI,AX
  406.     AND    SI,30H
  407.     MOV    AX,0B800H    ;COLOR CARD RAM
  408.     MOV    CX,8192        ;WORD COUNT
  409.     CMP    SI,30H
  410.     JNE    CC@8
  411.     MOV    AX,0B000H    ;BW CARD RAM
  412.     MOV    CX,2048        ;WORD COUNT
  413. CC@8:
  414.     MOV    ES,AX
  415.     MOV    AH,15        ;VIDEO STATE
  416.     INT    10H
  417.     CMP    AL,4        ;GRAPHICS MODE?
  418.     JC    CC@9
  419.     CMP    SI,30H        ;BW CARD?
  420.     JE    CC@9
  421.     XOR    AX,AX        ;FILL WORD
  422.     JMP    SHORT CC@10
  423. CC@9:
  424.     MOV    AX,' '+7*256    ;FILL WORD
  425. CC@10:
  426.     XOR    DI,DI
  427.     CLD
  428.     REP    STOSW        ;CLEAR VIDEO MEMORY
  429.     MOV    AH,2        ;MOVE CURSOR
  430.     XOR    DX,DX        ;0,0 (HOME)
  431.     XOR    BH,BH        ;ACTIVE PAGE
  432.     INT    10H
  433.     RET
  434. ;
  435. ;
  436. ;
  437. ;    gets(buff)
  438. ;
  439. ;
  440.     PUBLIC    QZGETS
  441. QZGETS:
  442.     POP    BX
  443.     POP    DX
  444.     PUSH    DX
  445.     PUSH    BX
  446.     SUB    DX,2
  447.     MOV    BP,DX
  448.     MOV    CX,[BP]
  449.     MOV    AX,004FH    ;ASSUMED LENGTH = 80 CHARS - 1 FOR EOL
  450.     MOV    [BP],AX        ;SET UP BUFFER THE WAY PC-DOS WANTS IT
  451.     PUSH    DS
  452.     MOV    AX,SS
  453.     MOV    DS,AX
  454.     MOV    AH,GETSTR
  455.     INT    21H
  456.     POP    DS
  457.     MOV    AX,[BP]        ;LENGTH IN AH
  458.     MOV    [BP],CX        ;RESTORE SAVED BYTES
  459.     ADD    BP,2
  460.     MOV    BX,BP
  461.     MOV    AL,AH
  462.     CBW
  463.     ADD    BP,AX
  464.     XOR    AL,AL
  465.     MOV    [BP],AL        ;INSERT C:PC STRING TERMINATOR
  466.     CALL    PUTLF
  467.     RET
  468. ;
  469. PUTLF:
  470.     MOV    AH,PUTCH
  471.     MOV    DL,LF
  472.     INT    21H
  473.     RET
  474. ;
  475. ;
  476. ;    getchar()
  477. ;
  478. ;
  479.     PUBLIC    QZGETCHAR
  480. QZGETCHAR:
  481.     MOV    AH,GETCH
  482.     INT    21H
  483.     MOV    BL,AL
  484.     XOR    BH,BH
  485.     CMP    AL,CTRLZ
  486.     JNZ    GETC1
  487.     MOV    BX,-1
  488. GETC1:
  489.     CMP    AL,EOL
  490.     JNZ    GC2
  491.     CALL    PUTLF
  492. GC2:
  493.     RET
  494. ;
  495. ;
  496. ;    putchar(c)
  497. ;
  498. ;
  499.     PUBLIC    QZPUTCHAR
  500. QZPUTCHAR:
  501.     POP    BX
  502.     POP    DX
  503.     PUSH    DX
  504.     PUSH    BX
  505.     MOV    AH,PUTCH
  506.     INT    21H
  507.     MOV    BL,DL
  508.     CMP    DL,EOL
  509.     JNZ    PUTC1
  510.     CALL    PUTLF
  511. PUTC1:
  512.     XOR    BH,BH
  513.     RET
  514. ;
  515. ;
  516. ;    puts(cp)
  517. ;
  518. ;
  519.     PUBLIC    QZPUTS
  520. QZPUTS:
  521.     POP    CX
  522.     POP    BP
  523.     PUSH    BP
  524.     PUSH    CX
  525.     MOV    AH,PUTCH
  526. PS1:
  527.     MOV    DL,[BP]
  528.     OR    DL,DL
  529.     JNZ    PS2
  530.     RET
  531. PS2:
  532.     INC    BP
  533.     INT    21H
  534.     JMP    PS1
  535. ;
  536. ;
  537. ;    Run Time Initialize
  538. ;
  539. ;
  540. CCGO:
  541.     MOV    CL,4        ;SHIFT COUNT
  542.     MOV    AX,STACK
  543.     MOV    SS,AX
  544.     MOV    BX,DS
  545.     SUB    AX,BX
  546.     SAL    AX,CL        ;MAKE DIFF 16 BITS
  547.     NEG    AX
  548.     ADD    AX,DS:6
  549.     MOV    SP,AX        ;MAX STACK POINTER
  550.     PUSH    DS        ;SAVE PREFIX ADDR
  551.     SUB    AX,AX
  552.     PUSH    AX        ;LONG EXIT ADDRESS IS NOW ON TOP
  553.     MOV    AX,DATASEG
  554.     PUSH    DS
  555.     MOV    DS,AX
  556.     MOV    AH,GETDFLT
  557.     INT    21H
  558.     INC    AL
  559.     MOV    BX,OFFSET DFLTDSK
  560.     MOV    [BX],AL
  561.     POP    DS
  562.     EXTRN    QZMAIN:NEAR
  563.     CALL    QZMAIN    ;EXECUTE USER'S small-c:PC PROGRAM
  564. ; FALL THRU TO EXIT CODE
  565. ;
  566. ;
  567. ;    exit()
  568. ;
  569.     PUBLIC    QZEXIT
  570. QZEXIT:
  571.     MOV    CL,4
  572.     MOV    AX,SS
  573.     MOV    BX,DS
  574.     SUB    AX,BX
  575.     SAL    AX,CL
  576.     NEG    AX
  577.     ADD    AX,DS:6
  578.     SUB    AX,4
  579.     MOV    SP,AX        ;PRUNE STACK
  580.     MOV    AX,DATASEG
  581.     PUSH    DS
  582.     MOV    DS,AX
  583.     MOV    BX,OFFSET DFLTDSK
  584.     MOV    DL,[BX]
  585.     DEC    DL
  586.     MOV    AH,SELECT
  587.     INT    21H
  588.     POP    DS
  589.     DB    0CBH        ;LONG RETURN TO DOS
  590. ;
  591. ;
  592. ;    fopen(name,mode)
  593. ;
  594.     PUBLIC    QZFOPEN
  595. QZFOPEN:
  596.     POP    AX
  597.     POP    CX    ;MODE
  598.     POP    SI    ;PREPARE FOR PARSE
  599.     PUSH    SI
  600.     PUSH    CX
  601.     PUSH    AX
  602.     PUSH    CX    ;SAVE MODE
  603.     CALL    GRABIO    ;GET FCB
  604.     POP    CX    ;RESTORE MODE FOR LATER USE
  605.     OR    BX,BX    ;ANY LUCK IN GETTING AN FCB?
  606.     JNZ    FO1
  607.     RET        ;NOPE
  608. FO1:
  609.     MOV    DX,BX        ;SAVE OFFSET
  610.     PUSH    DS    ;SAVE CALLER'S DS
  611.     MOV    AX,DATASEG
  612.     MOV    DS,AX    ;ADDRESS OUR DATA SEGMENT
  613.     ADD    BX,FCBSIZE    ;OFFSET OF BUFFER
  614.     MOV    AX,BX
  615.     ADD    AX,BUFFER    ;IO AREA OFFSET
  616.     MOV    [BX]+NEXTP,AX    ;NEXT AVAILABLE CHAR
  617.     PUSH    DS
  618.     MOV    AX,DS
  619.     MOV    ES,AX
  620.     MOV    DI,DX        ;ES:DI -> FCB
  621.     MOV    AX,SS
  622.     MOV    DS,AX        ;DS:SI -> NAME
  623.     MOV    AH,PARSE
  624.     XOR    AL,AL        ;PARSE WITHOUT SKIPPING ANYTHING
  625.     INT    21H
  626.     POP    DS        ;RESTORE OUR DS
  627.     OR    AL,AL        ;ANY LUCK?
  628.     JNZ    FORET        ;JUMP IF NOT
  629.     MOV    AL,[DI]+1    ;SEE IF WE HAD A VALID FILENAME
  630.     CMP    AL,20H        ;BLANK?
  631.     JNZ    FO2        ;NOPE, SO IT MUST BE SOMETHING THERE
  632. FORET:
  633.     POP    DS        ;RESTORE CALLER'S DS
  634.     XOR    BX,BX        ;SET RETURN STATUS
  635.     RET            ;LEAVE
  636. FO2:
  637.     MOV    BX,DX        ;RESTORE OFFSET OF FCB
  638.     MOV    AL,[BX]        ;DRIVE
  639.     PUSH    DX        ;SAVE ACCROSS CALL
  640.     PUSH    CX
  641.     PUSH    AX
  642.     CALL    PCDOSDSK    ;SELECT IT
  643.     POP    AX
  644.     POP    BP        ;MODE OFFSET INTO BP FOR STACK ACCESS
  645.     POP    DX
  646.     MOV    AL,[BP]        ;GET MODE CHAR
  647.     CMP    AL,72H        ;MODE='r'
  648.     JZ    FO3
  649.     CMP    AL,52H        ;MODE='R'
  650.     JNZ    FO5
  651. FO3:
  652.     MOV    AH,OPEN
  653.     INT    21H        ;OPEN THE FILE
  654.     OR    AL,AL
  655.     JZ    FO4        ;NO ERROR JUMP
  656. FO3@1:
  657.     PUSH    DX        ;FCB OFFSET
  658.     CALL    FREEIO        ;GIVE IT UP
  659.     POP    DX
  660.     JMP    FORET
  661. FO4:
  662.     XOR    AX,AX
  663. FO4@1:
  664.     MOV    [BX]+FCBSIZE+UNUSED,AX    ;SET UNUSED BUFFER BYTES
  665.     XOR    AX,AX
  666.     MOV    [BX]+32,AL        ;INIT SOME FCB FIELDS
  667.     MOV    [BX]+33,AX
  668.     MOV    [BX]+35,AX
  669.     MOV    AX,BUFSIZ
  670.     MOV    [BX]+14,AX
  671.     POP    DS            ;RESTORE CALLER'S DS
  672.     RET                ;LEAVE WITH BX SET TO FCB OFFSET
  673. FO5:
  674.     CMP    AL,77H        ;MODE='w'
  675.     JZ    FO6
  676.     CMP    AL,57H        ;MODE='W'
  677.     JNZ    FO3@1        ;TAKE ERROR EXIT
  678. FO6:
  679.     MOV    AH,DELETE
  680.     INT    21H        ;DELETE FILE IF IT CURRENTLY EXISTS
  681.     MOV    AH,CREATE
  682.     INT    21H        ;CREATE IT
  683.     OR    AL,AL        ;OK?
  684.     JNZ    FO3@1        ;TAKE ERROR EXIT IF NOT
  685.     MOV    BX,DX
  686.     MOV    AL,WRTFLG
  687.     MOV    [BX]+FLAG,AL    ;INDICATE HOW FILE IS OPENED
  688.     MOV    AX,BUFSIZ    ;NUMBER OF UNUSED BUFFER POSITIONS
  689.     JMP    FO4@1
  690. ;
  691. ;
  692. ;
  693. ;    grabio()
  694. ;
  695. ;
  696. GRABIO:
  697.     PUSH    DS
  698.     MOV    AX,DATASEG
  699.     MOV    DS,AX
  700.     MOV    BX,OFFSET IOBUFS+FLAG
  701.     MOV    CX,NBUFS
  702.     MOV    AL,FREEFLG
  703. GI1:
  704.     CMP    AL,[BX]
  705.     JZ    GI2
  706.     ADD    BX,FCBSIZE+BUFFER+BUFSIZ
  707.     LOOP    GI1
  708.     XOR    BX,BX
  709.     JMP    GI3
  710. GI2:
  711.     XOR    AL,AL
  712.     MOV    [BX],AL
  713.     SUB    BX,FLAG
  714. GI3:
  715.     POP    DS
  716.     RET
  717. ;
  718. ;
  719. ;
  720. ;    freeio(unit)
  721. ;
  722. ;
  723. FREEIO:
  724.     POP    CX
  725.     POP    BX
  726.     PUSH    BX
  727.     MOV    AL,FREEFLG
  728.     MOV    [BX]+FLAG,AL
  729.     XOR    BX,BX
  730.     JMP    CX
  731. ;
  732. ;
  733. ;
  734. ;    pcdosdsk(drive)
  735. ;
  736. ;
  737. PCDOSDSK:
  738.     POP    CX
  739.     POP    DX
  740.     PUSH    DX
  741.     OR    DL,DL
  742.     JNZ    PD1
  743. ; SELECT DEFAULT DRIVE
  744.     PUSH    BX
  745.     MOV    BX,OFFSET DFLTDSK
  746.     MOV    DL,[BX]
  747.     POP    BX
  748. PD1:
  749.     DEC    DL
  750.     MOV    AH,SELECT
  751.     INT    21H
  752.     JMP    CX
  753. ;
  754. ;
  755. ;
  756. ;    fclose(unit)
  757. ;
  758. ;
  759.     PUBLIC    QZFCLOSE
  760. QZFCLOSE:
  761.     POP    CX
  762.     POP    BX        ;FCB OFFSET
  763.     PUSH    BX
  764.     PUSH    CX
  765.     MOV    SI,1        ;DEFAULT RETURN CODE
  766.     PUSH    DS        ;SAVE CALLER'S DS
  767.     MOV    AX,DATASEG
  768.     MOV    DS,AX
  769.     MOV    AL,WRTFLG
  770.     AND    AL,[BX]+FLAG    ;OPENED FOR WRITE?
  771.     JZ    FC3        ;JUMP IF NOT
  772.     MOV    AX,CTRLZ
  773.     PUSH    AX        ;CHAR TO WRITE
  774.     PUSH    BX        ;UNIT TO GO TO
  775.     CALL    QZPUTC        ;CTRLZ AT FILE END
  776.     POP    BX
  777.     POP    AX
  778. ; FILL BUFFER WITH FILL CHAR
  779.     MOV    DX,BX
  780.     MOV    AX,[BX]+FCBSIZE+NEXTP        ;OFFSET OF NEXT AVAILABLE CHAR
  781.     MOV    CX,DX
  782.     ADD    CX,FCBSIZE+BUFFER+BUFSIZ    ;OFFSET PAST LAST IOAREA BYTE
  783.     SUB    CX,AX        ;NUMBER OF CHARS TO FILL
  784.     PUSH    CX        ;SAVE UNUSED BYTE COUNT
  785.     JLE    FC0        ;JUMP IF NONE
  786.     MOV    DI,AX        ;START ADDRESS ES:DI
  787.     MOV    AX,DS
  788.     MOV    ES,AX
  789.     MOV    AL,0    ;FILL CHAR
  790.     CLD            ;LEFT TO RIGHT
  791.     REP    STOSB        ;FILL BUFFER
  792. FC0:
  793.     MOV    AX,SEQWRITE
  794.     PUSH    AX
  795.     PUSH    DX        ;FUNCTION AND UNIT NOW ON STACK
  796.     CALL    PCDOSIO        ;WRITE SECTOR
  797.     MOV    AX,BX        ;SAVE RETURN CODE
  798.     POP    BX        ;RESTORE UNIT
  799.     POP    CX
  800.     OR    AX,AX
  801.     JNS    FC1
  802.     MOV    SI,0
  803. FC1:
  804.     POP    CX        ;RESTORE UNUSED COUNT
  805.     NEG    CX        ;PREPARE TO REDUCE DOS COUNT
  806.     JNS    FC3        ;NO SIGN IMPLIES  DOS COUNT IS OK
  807.     MOV    AX,1        ;PREPARE FOR OVERFLOW
  808.     ADD    [BX]+16,CX    ;NEW LOW PART
  809.     JNO    FC3        ;NO OVERFLOW => NO HIGH PART CHANGE
  810.     ADD    [BX]+18,AX    ;NEW HIGH PART
  811. FC3:
  812.     MOV    DX,BX
  813.     MOV    AH,CLOSE
  814.     INT    21H        ;CLOSE FILE
  815.     OR    AL,AL
  816.     JNS    FC2
  817.     MOV    SI,0
  818. FC2:
  819.     PUSH    BX
  820.     CALL    FREEIO
  821.     POP    BX
  822.     POP    DS
  823.     MOV    BX,SI
  824.     RET
  825. ;
  826. ;
  827. ;
  828. ;    pcdosio(fn,unit)
  829. ;
  830. ;
  831. PCDOSIO:
  832.     POP    CX
  833.     POP    DX        ;UNIT= OFFSET IN DS OF FCB
  834.     POP    BX        ;FUNCTION WANTED
  835.     PUSH    BX
  836.     PUSH    DX
  837.     PUSH    CX
  838.     PUSH    DS        ;SAVE CALLER'S DS
  839.     MOV    AX,DATASEG
  840.     MOV    DS,AX
  841.     XOR    AH,AH
  842.     XCHG    BX,DX
  843.     MOV    AL,[BX]        ;DRIVE NUMBER
  844.     XCHG    BX,DX
  845.     PUSH    DX
  846.     PUSH    AX
  847.     CALL    PCDOSDSK    ;SELECT IT
  848.     POP    AX
  849.     POP    DX
  850.     MOV    CX,DX        ;SAVE UNIT
  851.     ADD    DX,FCBSIZE+BUFFER    ;IO AREA OFFSET
  852.     MOV    AH,DMA
  853.     INT    21H        ;SET TRANSFER ADDRESS
  854.     MOV    DX,CX        ;DS:DX = FCB ADDRESS
  855.     MOV    AH,BL        ;FUNCTION CODE
  856.     INT    21H
  857.     MOV    CL,AL        ;STATUS
  858.     MOV    AH,DMA
  859.     POP    DS        ;RESET DS TO PREFIX
  860.     MOV    DX,80H
  861.     INT    21H        ;DMA BACK TO DEFAULT
  862.     MOV    AL,BL        ;SAVE FUNCTION
  863.     XOR    BX,BX
  864.     OR    CL,CL
  865.     JZ    PDI1
  866.     CMP    AL,SEQREAD    ;DID USER READ?
  867.     JNZ    PDI0        ;CONSIDER IT AN ERROR
  868.     CMP    CL,03H        ;PARTIALLY FULL BUFFER?
  869.     JZ    PDI1        ;THAT'S OK
  870. PDI0:
  871.     NOT    BX
  872. PDI1:
  873.     RET
  874. ;
  875. ;
  876. ;
  877. ;    getc (unit)
  878. ;
  879. ;
  880.     PUBLIC    QZGETC
  881. QZGETC:
  882.     POP    CX
  883.     POP    BX        ;UNIT
  884.     PUSH    BX
  885.     PUSH    CX
  886.     PUSH    BX
  887.     CALL    CGET        ;GET NEXT CHARACTER
  888.     POP    DX        ;UNIT
  889.     CMP    BL,EOL        ;END OF LINE
  890.     JNZ    GC1        ;GO ON BACK IF NOT
  891.     PUSH    BX        ;SAVE EOL ON STACK
  892.     PUSH    DX        ;UNIT
  893.     CALL    CGET        ;ABSORB LF
  894.     POP    DX
  895.     POP    BX        ;RETURN EOL
  896. GC1:
  897.     RET
  898. ;
  899. ;
  900. ;
  901. ;    cget(unit)
  902. ;
  903. ;
  904. CGET:
  905.     POP    CX
  906.     POP    BX
  907.     MOV    DX,BX
  908.     PUSH    BX
  909.     PUSH    CX
  910.     PUSH    DS
  911.     MOV    AX,DATASEG
  912.     MOV    DS,AX
  913.     MOV    AL,EOFFLG
  914.     AND    AL,[BX]+FLAG        ;END OF FILE EXIST?
  915.     JZ    CG1            ;NOPE
  916. CG0:
  917.     POP    DS
  918.     MOV    BX,-1            ;ERROR RETURN
  919.     RET
  920. CG1:
  921.     MOV    AX,[BX]+FCBSIZE+NEXTP    ;BUFFER OFFSET OF NEXT CHARACTER
  922.     MOV    CX,[BX]+FCBSIZE+UNUSED    ;NUM CHARS REMAINING IN BUF
  923.     OR    CX,CX
  924.     JNZ    CG2            ;SOME LEFT
  925.     ;READ NEW SECTOR
  926.     MOV    AX,SEQREAD
  927.     PUSH     AX            ;FUNCTION
  928.     PUSH    DX            ;UNIT
  929.     CALL    PCDOSIO            ;READ SECTOR
  930.     POP    DX
  931.     POP    AX
  932.     OR    BH,BL            ;OK?
  933.     JNZ    CG0            ;JUMP IF NOT
  934.     MOV    BX,DX            ;RESTORE UNIT
  935.     MOV    CX,BUFSIZ        ;NEW COUNT
  936.     MOV    AX,DX
  937.     ADD    AX,FCBSIZE+BUFFER    ;NEW NEXT CHAR OFFSET
  938. CG2:
  939.     DEC    CX            ;REDUCE UNUSED
  940.     MOV    [BX]+FCBSIZE+UNUSED,CX
  941.     MOV    CX,AX
  942.     INC    CX            ;BUMP UP NEXT CHAR POINTER
  943.     MOV    [BX]+FCBSIZE+NEXTP,CX
  944.     MOV    BX,AX            ;OFFSET OF CHAR TO RETURN
  945.     MOV    AL,[BX]
  946.     CMP    AL,CTRLZ        ;IS IT EOF MARKER?
  947.     JNZ    CG3            ;JUMP IF NOT
  948.     MOV    BX,DX            ;UNIT
  949.     MOV    AH,EOFFLG
  950.     OR    [BX]+FLAG,AH        ;SET END OF FILE IN FCB
  951.     JMP    CG0
  952. CG3:
  953.     MOV    BL,AL            ;CHAR TO RETURN
  954.     XOR    BH,BH
  955.     POP    DS
  956.     RET
  957. ;
  958. ;
  959. ;
  960. ;    putc(char,unit)
  961. ;
  962. ;
  963. ;
  964.     PUBLIC    QZPUTC
  965. QZPUTC:
  966.     POP    CX
  967.     POP    BX        ;UNIT
  968.     POP    AX        ;CHAR
  969.     PUSH    AX
  970.     PUSH    BX
  971.     PUSH    CX
  972.     PUSH    AX        ;CHAR
  973.     PUSH    BX        ;UNIT
  974.     CALL    CPUT        ;PUT OUT CHAR
  975.     POP    DX        ;UNIT
  976.                 ;LEAVE CHAR ON STACK AS RETURN VALUE
  977.     OR    BH,BH        ;ERROR?
  978.     JS    PC2        ;JUMP IF SO
  979.     CMP    BL,EOL        ;DID EOL GO OUT?
  980.     JNZ    PC1        ;JUMP IF NOT
  981.     MOV    AX,LF        ;PUT OUT LF ALSO
  982.     PUSH     AX
  983.     PUSH    DX
  984.     CALL    CPUT
  985.     POP    DX
  986.     POP    AX
  987.     OR    BH,BH        ;ERROR?
  988.     JS    PC2        ;JUMP IF SO
  989. PC1:
  990.     POP    BX        ;RETURN CHAR PASSED IN
  991.     RET
  992. PC2:
  993.     POP    CX        ;CLEAR CHAR OFF STACK
  994.     MOV    BX,-1        ;ERROR RETURN
  995.     RET
  996. ;
  997. ;
  998. ;
  999. ;    cput(c,unit)
  1000. ;
  1001. ;
  1002. CPUT:
  1003.     POP    CX
  1004.     POP    BX        ;UNIT
  1005.     POP    SI        ;CHAR
  1006.     PUSH    SI
  1007.     PUSH    BX
  1008.     PUSH    CX
  1009.     PUSH    DS
  1010.     MOV    AX,DATASEG
  1011.     MOV    DS,AX
  1012.     MOV    DX,BX
  1013.     MOV    AX,[BX]+FCBSIZE+NEXTP    ;NEXT CHAR OFFSET
  1014.     MOV    CX,[BX]+FCBSIZE+UNUSED    ;UNUSED CHAR COUNT
  1015.     OR    CX,CX
  1016.     JNZ    CP2            ;JUMP IF ROOM AVAILABLE
  1017.     MOV    AX,SEQWRITE
  1018.     PUSH    AX        ;FUNCTION
  1019.     PUSH    DX        ;UNIT
  1020.     CALL    PCDOSIO        ;SECTOR WRITE
  1021.     POP    DX
  1022.     POP    AX
  1023.     OR    BH,BL
  1024.     JZ    CP1        ;JUMP IF OK
  1025. CP0:
  1026.     POP    DS
  1027.     MOV    BX,-1        ;ERROR RETURN
  1028.     RET
  1029. CP1:
  1030.     MOV    CX,BUFSIZ
  1031.     MOV    AX,DX
  1032.     ADD    AX,FCBSIZE+BUFFER
  1033.     MOV    BX,DX
  1034. CP2:
  1035.     DEC    CX        ;REDUCE UNUSED
  1036.     MOV    [BX]+FCBSIZE+UNUSED,CX
  1037.     MOV    CX,AX
  1038.     INC    CX
  1039.     MOV    [BX]+FCBSIZE+NEXTP,CX    ;NEW NEXT CHAR OFFSET
  1040.     MOV    BX,AX
  1041.     MOV    AX,SI        ;CHAR TO PUT
  1042.     MOV    [BX],AL        ;BUFFER CHARACTER
  1043.     MOV    BX,AX
  1044.     POP    DS
  1045.     RET
  1046. ;
  1047. CSEG    ENDS
  1048. STACK    SEGMENT BYTE PUBLIC 'stack'
  1049. STACK    ENDS
  1050. DUMMY    SEGMENT BYTE STACK 'dummy'
  1051.     DB    128 DUP(?)
  1052. DUMMY    ENDS
  1053.     END    CCGO
  1054.